from rest_framework.permissions import BasePermission, SAFE_METHODS


class IsOwnerOrReadOnly(BasePermission):
    message = 'You must be the owner to update'

    def safe_methods_or_owner(self, request, func):
        if request.method in SAFE_METHODS:
            return True

        return func()

    def has_permission(self, request, view):
        # if request.method in SAFE_METHODS:
        #     return True
        #
        # return request.user.is_authenticated
        return self.safe_methods_or_owner(
            request,
            lambda: request.user.is_authenticated
        )

    def has_object_permission(self, request, view, obj):
        """
        进行非安全请求时，
        由于需要验证当前评论的作者和当前登录的用户是否为同一个人，
        这里用到了 def has_object_permission(...) 这个钩子方法，
        方法参数中的 obj 即为评论模型的实例。
        看起来只需要实现这个 def has_object_permission(...) 就可以了，
        但还有一点点小问题：此方法是晚于视图集中的
        def perform_create(author=self.request.user) 执行的。
        如果用户未登录时新建评论，由于用户不存在，接口会抛出 500 错误。

        本着即使出错也要做出正确错误提示的原则，
        增加了 def has_permission(...) 方法。
        此方法早于 def perform_create(...) 执行，
        因此能够对用户登录状态做一个预先检查。
        """
        # if request.method in SAFE_METHODS:
        #     return True
        #
        # return request.user == obj.author
        return self.safe_methods_or_owner(
            request,
            lambda: obj.author == request.user
        )





